package com.gexin.common.utils;

import com.jfinal.plugin.redis.Redis;
import redis.clients.jedis.Jedis;

import java.util.Collections;

/**
 * @author 肖得明
 * @Title: RedisLockTool
 * @ProjectName maven-web-wmb
 * @Description: TODO
 * @date 2019/10/2917:27
 */
public class RedisLockTool {

	private static final String LOCK_SUCCESS = "OK";
	private static final String SET_IF_NOT_EXIST = "NX";
	private static final String SET_WITH_EXPIRE_TIME = "PX";
	private static final Long RELEASE_SUCCESS = 1L;

	/**
	 * 尝试获取分布式锁
	 *
	 * @param jedis      Redis客户端
	 * @param lockKey    锁
	 * @param requestId  请求标识  不能重复
	 * @param expireTime 超期时间  毫秒1000 =1秒
	 * @return 是否获取成功
	 */
	private static boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
		Jedis jedis = Redis.use().getJedis();
		String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
		jedis.close();
		if (LOCK_SUCCESS.equals(result)) {
			return true;
		}
		return false;
	}

	/**
	 * 获取锁
	 * @param lockKey 锁的Key 不能重复
	 * @param expireTime   超期时间  毫秒1000 =1秒
	 * @return
	 */
	public static boolean getLock(String lockKey, int expireTime) {
		Jedis jedis = Redis.use().getJedis();
		String result = jedis.set(lockKey, "1", SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
		jedis.close();
		if (LOCK_SUCCESS.equals(result)) {
			return true;
		}
		return false;
	}

	public static boolean releaseLock(String lockKey) {
		Jedis jedis = Redis.use().getJedis();
		String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
		Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList("1"));
		jedis.close();
		if (RELEASE_SUCCESS.equals(result)) {
			return true;
		}
		return false;

	}

	/**
	 * 释放分布式锁
	 *
	 * @param jedis     Redis客户端
	 * @param lockKey   锁
	 * @param requestId 请求标识
	 * @return 是否释放成功
	 */
	private static boolean releaseDistributedLock(String lockKey, String requestId) {
		Jedis jedis = Redis.use().getJedis();
		String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
		Object result = jedis.eval(script, Collections.singletonList(lockKey),
				Collections.singletonList(requestId));
		jedis.close();
		if (RELEASE_SUCCESS.equals(result)) {
			return true;
		}
		return false;

	}
}
